﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FigureDraw;
using FigureDraw.Graphic;
using FigureDraw.Diagram;
using FigureDraw.Shapes;
using FigureDraw.Shapes.ActivityShape;
using System.IO;
using FigureDraw.Shapes.DataFlowShape;
using FigureDraw.Shapes.FlowchartShape;
using FigureDraw.Graphic.GDIPlus;
using FigureDraw.Graphic.Cairo;
using FigureDraw.Shapes.Effect;
using FigureDrawApp.Helper;

namespace FigureDrawApp
{
    public partial class MainForm : Form
    {
        private CommonGraphic graphic;
        private MyPicture myPicture;
        private Point startPoint;
        private Point endPoint;
        private MyShape current;
        private string library;
        private MyColorInfo BrushColor;
        private double StrokeWidth;
        private MyColorInfo StrokeColor;
        private MyPanel panel;

        public MainForm()
        {
            InitializeComponent();

            //Init panel
            panel = new MyPanel();
            panel.Paint += panel_Paint;
            panel.MouseDown += panel_MouseDown;
            panel.MouseMove += panel_MouseMove;
            panel.MouseUp += panel_MouseUp;
            this.Controls.Add(panel);
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            myPicture = new MyPicture();
            startPoint = new Point(0, 0);
            endPoint = new Point(0, 0);
            current = new MyLine();
            library = "GDI";
            StrokeWidth = 1;
            StrokeColor = new MyColorInfo(Color.Black.R, Color.Black.G, Color.Black.B);
            BrushColor = new MyColorInfo(Color.White.R, Color.White.G, Color.White.B);
        }

        void panel_Paint(object sender, PaintEventArgs e)
        {
            switch (library)
            {
                case "GDI":
                    graphic = new GDIPlusScreenGraphic(e.Graphics);               
                    break;
                case "Cairo":
                    graphic = new CairoScreenGraphic(e.Graphics);                  
                    e.Graphics.ReleaseHdc();
                    break;
            }

            myPicture.Draw(graphic);
            Draw(graphic, startPoint, endPoint);
        }

        private void Draw(CommonGraphic g, Point diem_dau, Point diem_duoi)
        {
            current.StartPoint = MyConverter.MyPointConverter(diem_dau);
            current.EndPoint = MyConverter.MyPointConverter(diem_duoi);
            current.StrokeWidth = StrokeWidth;
            current.StrokeColor = StrokeColor;
            current.BrushColor = BrushColor;
            MyShape temp = current.Clone();
            foreach (var effect in myPicture.LstEffect)
                temp = effect.AttachEffect(temp);

            if (!(diem_dau.X == 0 && diem_dau.Y == 0 &&
                diem_duoi.X == 0 && diem_duoi.Y == 0))
            {
                current.Draw(g);
                temp.Draw(g);
            }
            
        }

        private void btnGDIPlus_Click(object sender, EventArgs e)
        {
            library = "GDI";
            panel.Invalidate();
        }

        private void btnCairo_Click(object sender, EventArgs e)
        {
            library = "Cairo";
            panel.Invalidate();
        }

        void panel_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                startPoint = e.Location;
                endPoint = e.Location;
            }
        }

        void panel_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                endPoint = e.Location;
                panel.Invalidate();
            }
        }

        void panel_MouseUp(object sender, MouseEventArgs e)
        {
            if (startPoint.X != endPoint.X && startPoint.Y != endPoint.Y)
            {
                if (current != null)
                {
                    current.StartPoint = MyConverter.MyPointConverter(startPoint);
                    current.EndPoint = MyConverter.MyPointConverter(endPoint);
                    current.StrokeWidth = StrokeWidth;
                    current.StrokeColor = StrokeColor;
                    current.BrushColor = BrushColor;
                    myPicture.Add(current.Clone());
                }
            }
            
            startPoint = new Point(0, 0);
            endPoint = new Point(0, 0);
        }

        private void btn_DrawLine_Click(object sender, EventArgs e)
        {
            current = new MyLine();
        }

        private void btn_DrawRec_Click(object sender, EventArgs e)
        {
            current = new MyRectangle();
        }

        private void btn_DrawEllipse_Click(object sender, EventArgs e)
        {
            current = new MyEllipse();
        }

        private void btn_DrawFlower_Click(object sender, EventArgs e)
        {
            current = new MyFlower();
        }

        private void btn_DrawStar_Click(object sender, EventArgs e)
        {
            current = new MyStar();
        }

        private void btn_Activity_BatDau_Click(object sender, EventArgs e)
        {
            current = new BeginActivity();
        }

        private void btn_Activity_DauVao_Click(object sender, EventArgs e)
        {
            current = new InputActivity();
        }

        private void btn_Activity_XuLy_Click(object sender, EventArgs e)
        {
            current = new ProcessActivity();
        }

        private void btn_Activity_DauRa_Click(object sender, EventArgs e)
        {
            current = new OutputActivity();
        }

        private void btn_Activity_BuocChuyen_Click(object sender, EventArgs e)
        {
            current = new MoveActivity();
        }

        private void btn_Activity_DieuKien_Click(object sender, EventArgs e)
        {
            current = new ConditionActivity();
        }

        private void btn_Activity_KetThuc_Click(object sender, EventArgs e)
        {
            current = new EndActivity();
        }

        private void btn_New_Click(object sender, EventArgs e)
        {
            myPicture.Clear();
            UncheckAllToolStripButton(tsDiagram);
            UncheckAllToolStripButton(tsEffect);
            UncheckAllToolStripButton(tsBorderColor);
            UncheckAllToolStripButton(tsFillColor);
            UncheckAllToolStripButton(tsStrokeWidth);
            startPoint = new Point(0, 0);
            endPoint = new Point(0, 0);
            panel.Invalidate();
        }


        private void btn_Save_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "JPEG files (*.jpg)|*.jpg|PNG files (*.png)|*.png|SVG files (*.svg)|*.svg";
            saveFileDialog1.FilterIndex = 3;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    CommonGraphic myGraphic;
                    string filename = saveFileDialog1.FileName;
                    MyPoint fileSize = new MyPoint(panel.Width, panel.Height);

                    if (library == "GDI")
                    {
                        if (saveFileDialog1.FilterIndex == 1)
                        {
                            myGraphic = new GDIPlusJPEGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 2)
                        {
                            myGraphic = new GDIPlusPNGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 3)
                        {
                            myGraphic = new GDIPlusSVGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                    }
                    else
                    {
                        if (saveFileDialog1.FilterIndex == 1)
                        {
                            myGraphic = new CairoJPEGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 2)
                        {
                            myGraphic = new CairoPNGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 3)
                        {
                            myGraphic = new CairoSVGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                    }
                    MessageBox.Show("Save thành công");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Save thất bại: " + ex.Message);
                }
            }
        }

        private void btn_DFD_BatDau_Click(object sender, EventArgs e)
        {
            current = new BeginDataFlow();
        }

        private void btn_DFD_DauVao_Click(object sender, EventArgs e)
        {
            current = new InputDataFlow();
        }

        private void btn_DFD_XuLy_Click(object sender, EventArgs e)
        {
            current = new ProcessDataFlow();
        }

        private void btn_DFD_DauRa_Click(object sender, EventArgs e)
        {
            current = new OutputDataFlow();
        }

        private void btn_DFD_BuocChuyen_Click(object sender, EventArgs e)
        {
            current = new MoveDataFlow();
        }

        private void btn_DFD_KetThuc_Click(object sender, EventArgs e)
        {
            current = new EndDataFlow();
        }

        private void btn_Flowchart_BatDau_Click(object sender, EventArgs e)
        {
            current = new BeginFlowchart();
        }

        private void btn_Flowchart_DauVao_Click(object sender, EventArgs e)
        {
            current = new InputFlowchart();
        }

        private void btn_Flowchart_XuLy_Click(object sender, EventArgs e)
        {
            current = new ProcessFlowchart();
        }

        private void btn_Flowchart_DauRa_Click(object sender, EventArgs e)
        {
            current = new OutputFlowchart();
        }

        private void btn_Flowchart_BuocChuyen_Click(object sender, EventArgs e)
        {
            current = new MoveFlowchart();
        }

        private void btn_Flowchart_DieuKien_Click(object sender, EventArgs e)
        {
            current = new ConditionFlowchart();
        }

        private void btn_Flowchart_KetThuc_Click(object sender, EventArgs e)
        {
            current = new EndFlowchart();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_NetVe1_Click(object sender, EventArgs e)
        {
            StrokeWidth = 1;
        }

        private void btn_NetVe2_Click(object sender, EventArgs e)
        {
            StrokeWidth = 4;
        }

        private void btn_NetVe3_Click(object sender, EventArgs e)
        {
            StrokeWidth = 6;
        }

        private void btn_NetVe4_Click(object sender, EventArgs e)
        {
            StrokeWidth = 8;
        }


        private void btn_Color_Do_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Red.R, Color.Red.G, Color.Red.B);
        }

        private void btn_Color_Cam_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Orange.R, Color.Orange.G, Color.Orange.B);
        }


        private void btn_Color_Vang_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Yellow.R, Color.Yellow.G, Color.Yellow.B);
        }

        private void btn_Color_Luc_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Green.R, Color.Green.G, Color.Green.B);
        }

        private void btn_Color_Lam_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Turquoise.R, Color.Turquoise.G, Color.Turquoise.B);
        }

        private void btn_Color_Cham_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Blue.R, Color.Blue.G, Color.Blue.B);
        }

        private void btn_Color_Tim_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Purple.R, Color.Purple.G, Color.Purple.B);
        }

        private void btn_Color_Den_Click(object sender, EventArgs e)
        {
            StrokeColor = new MyColorInfo(Color.Black.R, Color.Black.G, Color.Black.B);
        }

        private void btn_Color_Custom_Click(object sender, EventArgs e)
        {
            ColorDialog dlg = new ColorDialog();
            dlg.Color = MyConverter.ColorConverter(StrokeColor);
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                StrokeColor = MyConverter.MyColorInfoConverter(dlg.Color);
            }
        }

        private void btn_Fill_Do_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Red.R, Color.Red.G, Color.Red.B);
        }

        private void btn_Fill_Cam_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Orange.R, Color.Orange.G, Color.Orange.B);
        }

        private void btn_Fill_Vang_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Yellow.R, Color.Yellow.G, Color.Yellow.B);
        }

        private void btn_Fill_Luc_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Green.R, Color.Green.G, Color.Green.B);
        }

        private void btn_Fill_Lam_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Turquoise.R, Color.Turquoise.G, Color.Turquoise.B);
        }

        private void btn_Fill_Cham_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Blue.R, Color.Blue.G, Color.Blue.B);
        }

        private void btn_Fill_Tim_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Purple.R, Color.Purple.G, Color.Purple.B);
        }

        private void btn_Fill_Custom_Click(object sender, EventArgs e)
        {
            if (BrushColor == null)
                BrushColor = new MyColorInfo(255, 255, 255);
            ColorDialog dlg = new ColorDialog();
            dlg.Color = MyConverter.ColorConverter(BrushColor);
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                BrushColor = MyConverter.MyColorInfoConverter(dlg.Color);
            }
        }

        private void btn_Fill_Den_Click(object sender, EventArgs e)
        {
            BrushColor = new MyColorInfo(Color.Black.R, Color.Black.G, Color.Black.B);
        }

        private void btn_ConvertToFlow_Click(object sender, EventArgs e)
        {
            myPicture.ConvertTo(FlowchartDiagram.Instance());
            startPoint = new Point(0, 0);
            endPoint = new Point(0, 0);
            panel.Invalidate();
        }

        private void btn_ConvertToDFD_Click(object sender, EventArgs e)
        {
            myPicture.ConvertTo(DataFlowDiagram.Instance());
            startPoint = new Point(0, 0);
            endPoint = new Point(0, 0);
            panel.Invalidate();
        }

        private void btn_ConvertToAct_Click(object sender, EventArgs e)
        {
            myPicture.ConvertTo(ActivityDiagram.Instance());
            startPoint = new Point(0, 0);
            endPoint = new Point(0, 0);
            panel.Invalidate();
        }

        private void btn_HieuUng_Shadow_Click(object sender, EventArgs e)
        {
            myPicture.SwitchEffect(new MyShadow());
            panel.Invalidate();
            Refresh();
        }

        private void btn_HieuUng_Highlight_Click(object sender, EventArgs e)
        {
            myPicture.SwitchEffect(new MyHighlight());
            panel.Invalidate();
            Refresh();
        }

        private void btn_HieuUng_Border_Click(object sender, EventArgs e)
        {
            myPicture.SwitchEffect(new MyBorder());
            panel.Invalidate();
            Refresh();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "JPEG files (*.jpg)|*.jpg|PNG files (*.png)|*.png|SVG files (*.svg)|*.svg";
            saveFileDialog1.FilterIndex = 3;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    CommonGraphic myGraphic;
                    string filename = saveFileDialog1.FileName;
                    MyPoint fileSize = new MyPoint(panel.Width, panel.Height);

                    if (library == "GDI")
                    {
                        if (saveFileDialog1.FilterIndex == 1)
                        {
                            myGraphic = new GDIPlusJPEGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 2)
                        {
                            myGraphic = new GDIPlusPNGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 3)
                        {
                            myGraphic = new GDIPlusSVGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                    }
                    else
                    {
                        if (saveFileDialog1.FilterIndex == 1)
                        {
                            myGraphic = new CairoJPEGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 2)
                        {
                            myGraphic = new CairoPNGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                        if (saveFileDialog1.FilterIndex == 3)
                        {
                            myGraphic = new CairoSVGGraphic(filename, fileSize);
                            myPicture.Draw(myGraphic);
                        }
                    }
                    MessageBox.Show("Save thành công");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Save thất bại: " + ex.Message);
                }
            }
        }


        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            btn_New_Click(sender, e);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Đỗ án môn Mẫu Thiết Kế Hướng Đối Tượng & Ứng Dụng" +
                "\n0912075 - Lê Anh Dũng" +
                "\n0912123 - Lê Phú Thái Hà" +
                "\n0912373 - Đỗ Minh Quân" +
                "\n0912392 - Châu Hoàn Sơn");
        }

        private void tsDiagram_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            CheckToolStripButton(tsDiagram, e);
        }

        private void tsBorderColor_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            CheckToolStripButton(tsBorderColor, e);
        }

        private void tsFillColor_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            CheckToolStripButton(tsFillColor, e);
        }

        private void tsStrokeWidth_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            CheckToolStripButton(tsStrokeWidth, e);
        }

        private void CheckToolStripButton(ToolStrip toolStrip, ToolStripItemClickedEventArgs e)
        {
            foreach (var item in toolStrip.Items)
            {
                if (item.GetType() == typeof(ToolStripButton))
                {
                    if (item == e.ClickedItem)
                        ((ToolStripButton)item).Checked = true;
                    else
                        ((ToolStripButton)item).Checked = false;
                }
            }
        }

        private void UncheckAllToolStripButton(ToolStrip toolStrip)
        {
            foreach (var item in toolStrip.Items)
            {
                if (item.GetType() == typeof(ToolStripButton))
                    ((ToolStripButton)item).Checked = false;
            }
        }
    }
}
